/*
 * Copyright 2010 Chad Retz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jdocng.shared.model;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import com.google.common.annotations.GwtCompatible;
import com.google.gson.annotations.Expose;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.SourcePosition;

/**
 * Implementation of {@link RootDoc}
 *
 * @author Chad Retz
 */
@XmlRootElement(name = "root")
@XmlType(name = "root")
@GwtCompatible(serializable = true)
@SuppressWarnings("serial")
public class RootDocImpl extends DocImpl implements RootDoc {

    //exposed fields
    
    @Expose
    private String[] classes;
    
    @Expose
    private String[] specifiedClasses;
    
    @Expose
    private String[] specifiedPackages;
    
    //non-exposed fields
    
    private transient ClassDocImpl[] classesLoaded;
    
    private transient String[][] optionsLoaded;
    
    private transient ClassDocImpl[] specifiedClassesLoaded;
    
    private transient PackageDocImpl[] specifiedPackagesLoaded;
    
    //RootDoc interface impl
    
    @Override
    public ClassDocImpl[] classes() {
        if (classesLoaded == null) {
            classesLoaded = getContext().getClassDocs(classes);
        }
        return classesLoaded;
    }
    
    @Override
    public ClassDocImpl classNamed(String qualifiedName) {
        for (ClassDocImpl doc : specifiedClasses()) {
            if (qualifiedName.equals(doc.qualifiedName())) {
                return doc;
            }
        }
        return null;
    }
    
    @Override
    public String[][] options() {
        if (optionsLoaded == null) {
            optionsLoaded = getContext().getConfiguration().buildOptionArray();
        }
        return optionsLoaded;
    }
    
    @Override
    public PackageDocImpl packageNamed(String name) {
        for (PackageDocImpl doc : specifiedPackages()) {
            if (name.equals(doc.name())) {
                return doc;
            }
        }
        return null;
    }
    
    @Override
    public ClassDocImpl[] specifiedClasses() {
        if (specifiedClassesLoaded == null) {
            specifiedClassesLoaded = getContext().getClassDocs(specifiedClasses);
        }
        return specifiedClassesLoaded;
    }
    
    @Override
    public PackageDocImpl[] specifiedPackages() {
        if (specifiedPackagesLoaded == null) {
            specifiedPackagesLoaded = getContext().getPackageDocs(specifiedPackages);
        }
        return specifiedPackagesLoaded;
    }
    
    //DocErrorReporter interface impl

    @Override
    public void printError(SourcePosition pos, String msg) {
        getContext().getLogger().printError(pos, msg);
    }
    
    @Override
    public void printError(String msg) {
        getContext().getLogger().printError(msg);
    }
    
    @Override
    public void printNotice(SourcePosition pos, String msg) {
        getContext().getLogger().printNotice(pos, msg);
    }
    
    @Override
    public void printNotice(String msg) {
        getContext().getLogger().printNotice(msg);
    }
    
    @Override
    public void printWarning(SourcePosition pos, String msg) {
        getContext().getLogger().printWarning(pos, msg);
    }
    
    @Override
    public void printWarning(String msg) {
        getContext().getLogger().printWarning(msg);
    }
    
    //other accessors
    
    public String[] getClasses() {
        return classes;
    }
    
    public void setClasses(String[] classes) {
        this.classes = classes;
    }
    
    public String[] getSpecifiedClasses() {
        return specifiedClasses;
    }
    
    public void setSpecifiedClasses(String[] specifiedClasses) {
        this.specifiedClasses = specifiedClasses;
    }
    
    public String[] getSpecifiedPackages() {
        return specifiedPackages;
    }
    
    public void setSpecifiedPackages(String[] specifiedPackages) {
        this.specifiedPackages = specifiedPackages;
    }
}
